package com.zheng.upms.rpc.service.impl;

import com.zheng.common.annotation.BaseService;
import com.zheng.common.base.BaseServiceImpl;
import com.zheng.upms.dao.mapper.UpmsScheduleJobMapper;
import com.zheng.upms.dao.model.UpmsScheduleJob;
import com.zheng.upms.dao.model.UpmsScheduleJobExample;
import com.zheng.upms.job.ScheduleUtils;
import com.zheng.upms.rpc.api.UpmsScheduleJobService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronTrigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* UpmsScheduleJobService实现
* Created by shuzheng on 2019/8/5.
*/
@Service
@Transactional
@BaseService
public class UpmsScheduleJobServiceImpl extends BaseServiceImpl<UpmsScheduleJobMapper, UpmsScheduleJob, UpmsScheduleJobExample> implements UpmsScheduleJobService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UpmsScheduleJobServiceImpl.class);

    @Autowired
    UpmsScheduleJobMapper upmsScheduleJobMapper;

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;

    @Override
    public void initScheduleJob() throws Exception {
        List<UpmsScheduleJob> scheduleJobList = this.selectByExample(new UpmsScheduleJobExample());

        if (CollectionUtils.isEmpty(scheduleJobList)) {
            return;
        }

        for (UpmsScheduleJob scheduleJob : scheduleJobList) {
            CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(schedulerFactoryBean.getScheduler(), scheduleJob.getJobName(), scheduleJob.getJobGroup());

            //不存在，创建一个
            if (cronTrigger == null) {
                ScheduleUtils.createScheduleJob(schedulerFactoryBean.getScheduler(), scheduleJob);
            } else {
                //已存在，那么更新相应的定时设置
                ScheduleUtils.updateScheduleJob(schedulerFactoryBean.getScheduler(), scheduleJob);
            }
        }
    }

    @Override
    public int saveScheduleJob(UpmsScheduleJob scheduleJob) throws Exception {
        //创建调度任务
        ScheduleUtils.createScheduleJob(schedulerFactoryBean.getScheduler(), scheduleJob);

        return this.insertSelective(scheduleJob);
    }

    @Override
    public int updateScheduleJob(UpmsScheduleJob scheduleJob) throws Exception {

//        //根据ID获取修改前的任务记录
        UpmsScheduleJob record = this.selectByPrimaryKey(scheduleJob.getId().intValue());

        //因为Quartz只能更新cron表达式，当更改了cron表达式以外的属性时，执行的逻辑是：先删除旧的再创建新的。注:equals排除了cron属性
        if(!scheduleJob.equals(record) && scheduleJob.getCron().equals(record.getCron())){
            //删除旧的任务
            ScheduleUtils.deleteScheduleJob(schedulerFactoryBean.getScheduler(), record.getJobName(), record.getJobGroup());
            //创建新的任务,保持原来任务的状态
            scheduleJob.setStatus(record.getStatus());
            ScheduleUtils.createScheduleJob(schedulerFactoryBean.getScheduler(), scheduleJob);
        }else {
            //当cron表达式和原来不一致才做更新
            if(!scheduleJob.getCron().equals(record.getCron())){
                //更新调度任务
                ScheduleUtils.updateScheduleJob(schedulerFactoryBean.getScheduler(), scheduleJob);
            }
        }
        return this.updateByPrimaryKeySelective(scheduleJob);
    }

    @Override
    public int deleteScheduleJob(String ids) throws Exception {
        if (StringUtils.isBlank(ids)) {
            return 0;
        }
        String[] idArray = ids.split("-");
        int count = 0;
        for (String idStr : idArray) {
            if (StringUtils.isBlank(idStr)) {
                continue;
            }
            Integer id = Integer.parseInt(idStr);
            UpmsScheduleJob scheduleJob = this.selectByPrimaryKey(id);
            //删除运行的任务
            ScheduleUtils.deleteScheduleJob(schedulerFactoryBean.getScheduler(), scheduleJob.getJobName(), scheduleJob.getJobGroup());
            int cou = this.deleteByPrimaryKey(id);
            count += cou;
        }
        return count;
    }

    @Override
    public void pauseJob(Long jobId) throws Exception {
        UpmsScheduleJob scheduleJob = this.selectByPrimaryKey(jobId.intValue());
        //暂停正在运行的调度任务
        ScheduleUtils.pauseJob(schedulerFactoryBean.getScheduler(), scheduleJob.getJobName(), scheduleJob.getJobGroup());
        //更新数据库状态为 禁用 0
        scheduleJob.setStatus(0);
        this.updateByPrimaryKeySelective(scheduleJob);
    }

    @Override
    public void resumeJob(Long jobId) throws Exception {
        UpmsScheduleJob scheduleJob = this.selectByPrimaryKey(jobId.intValue());
        //恢复处于暂停中的调度任务
        ScheduleUtils.resumeJob(schedulerFactoryBean.getScheduler(), scheduleJob.getJobName(), scheduleJob.getJobGroup());
        //更新数据库状态 启用 1
        scheduleJob.setStatus(1);
        this.updateByPrimaryKeySelective(scheduleJob);
    }

    @Override
    public void runOnce(Long jobId) throws Exception {
        UpmsScheduleJob scheduleJob = this.selectByPrimaryKey(jobId.intValue());
        //运行一次
        ScheduleUtils.runOnce(schedulerFactoryBean.getScheduler(), scheduleJob.getJobName(), scheduleJob.getJobGroup());
    }

}